import entity.HourlyReqSummary;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class Main {
	//NOTE 请使用 select `id`,app_id,`uri`,`date`,total_req_count,year_req_count,month_req_count,day_req_count,hour_req_count,success,fail,fail_auth,fail_sys_local,fail_sys_remote,fail_other,fail_pre_miss,fail_pre_invalid,fail_post_invalid from hourly_req_summary where uri='/ability/mark/getDMP-' and app_id='aotian_dmp';导出
	public static void main(String[] args){
//		test();
		String dmpFile = "d:/dmp.txt";
		handleFile(dmpFile);
		System.out.println(list.size());
//		System.out.println(list);
		write2file("d:/result.txt");
	}

	public static void test(){
		String line = "|    816 | aotian_dmp | /ability/mark/getDMP- | 2017-07-24 18:16:10 |       111619303 |      111619296 |       111619292 |             0 |              0 |     NULL | NULL |      NULL |           NULL |            NULL |       NULL |          NULL |             NULL |              NULL |";
		String[] ss = line.split("\\|");
//		System.out.println(ss.length);

		for(int i = 0; i != ss.length; ++i){
			System.out.println(i + " - [" + ss[i] + "]");
		}
	}

	/**
	 * @param dmpFile 要读取的文件
	 */
	public static void handleFile(String dmpFile){
		File file = new File(dmpFile);
		if(!file.exists()){
			System.err.println("文件[" + dmpFile + "]不存在!");
			return;
		}
		try{
			BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
			bufferedReader.lines().forEach(Main::handleLine);
		} catch(FileNotFoundException e){
			e.printStackTrace();
		}

	}

	private static List<HourlyReqSummary> list = new ArrayList<HourlyReqSummary>(512);
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static HourlyReqSummary tmpObj=new HourlyReqSummary();
	private static boolean flag=false;//（上一条操作和本条操作之间）是否有redis重置
	/**
	 * 处理行数据
	 * 有两种问题：一种是重复记录（需要忽略），一种是redis清空导致的重新计数
	 *
	 * @param line 一行记录
	 */
	public static void handleLine(String line){
//		System.out.println(line);
		String[] arr = line.split("\\|");
		if(arr == null || arr.length != 19){//见test()
			System.err.println("line信息不对，源line=[" + line + "]");
			return;
		}
		for(int i = 0; i != arr.length; ++i){
			if("NULL".equalsIgnoreCase(arr[i].trim())){
				arr[i] = "0";
			}
		}
//		System.out.println(line);
		HourlyReqSummary obj = new HourlyReqSummary();
		try{
			obj.setId(Integer.valueOf(arr[1].trim()));
			obj.setAppId(arr[2].trim());
			obj.setUri(arr[3].trim());
			obj.setDate(sdf.parse(arr[4].trim()));

			tmpObj.setId(Integer.valueOf(arr[1].trim()));
			tmpObj.setAppId(arr[2].trim());
			tmpObj.setUri(arr[3].trim());
			tmpObj.setDate(sdf.parse(arr[4].trim()));

			//特殊处理
			if(list.isEmpty()){
				long cur_totalReqCount = Long.parseLong(arr[5].trim());
				obj.setTotalReqCount(cur_totalReqCount);
				tmpObj.setTotalReqCount(cur_totalReqCount);
				long cur_yearReqCount = Long.parseLong(arr[6].trim());
				obj.setYearReqCount(cur_yearReqCount);
				tmpObj.setYearReqCount(cur_yearReqCount);
				long cur_monthReqCount = Long.parseLong(arr[7].trim());
				obj.setMonthReqCount(cur_monthReqCount);
				tmpObj.setMonthReqCount(cur_monthReqCount);
				long cur_dayReqCount = Long.parseLong(arr[8].trim());
				obj.setDayReqCount(cur_dayReqCount);
				tmpObj.setDayReqCount(cur_dayReqCount);
			} else{
				HourlyReqSummary lastObj = list.get(list.size() - 1);
				if(lastObj == null){
					return;
				}
				Date date = lastObj.getDate();
				if(date == null){
					System.err.println("property date is null???  " + lastObj);
				}

				Calendar lastCalendar = Calendar.getInstance();
				lastCalendar.setTime(date);
				Calendar curCalendar = Calendar.getInstance();
				curCalendar.setTime(sdf.parse(arr[4].trim()));

				//如果同一个小时（重启服务导致重复持久化），放弃本条
				if(lastCalendar.get(Calendar.YEAR) == curCalendar.get(Calendar.YEAR)
						&& lastCalendar.get(Calendar.MONTH) == curCalendar.get(Calendar.MONTH)
						&& lastCalendar.get(Calendar.DAY_OF_MONTH) == curCalendar.get(Calendar.DAY_OF_MONTH)
						&& lastCalendar.get(Calendar.HOUR_OF_DAY) == curCalendar.get(Calendar.HOUR_OF_DAY)
						){
					System.out.println("drop duplicated record: " + line);
					return;//DUANGDUANGDUANG
				}

				//redis清空导致的重新计数（FIXME 处理方式不对，因为会重复计算）
				long cur_totalReqCount = Long.parseLong(arr[5].trim());
				tmpObj.setTotalReqCount(cur_totalReqCount);
				if(cur_totalReqCount < lastObj.getTotalReqCount()){
//					cur_totalReqCount = lastObj.getTotalReqCount()+(cur_totalReqCount-tmpObj.getTotalReqCount()); //靠，这样累计是不对的，因为不断累计了！！！
				}
				obj.setTotalReqCount(cur_totalReqCount);

				long cur_yearReqCount = Long.parseLong(arr[6].trim());
				tmpObj.setYearReqCount(cur_yearReqCount);
				if(lastCalendar.get(Calendar.YEAR) == curCalendar.get(Calendar.YEAR)){
					if(cur_yearReqCount < lastObj.getYearReqCount()){//说明有重启
//						cur_yearReqCount += lastObj.getYearReqCount();
					}
				}
				obj.setYearReqCount(cur_yearReqCount);

				long cur_monthReqCount = Long.parseLong(arr[7].trim());
				tmpObj.setMonthReqCount(cur_monthReqCount);
				if(lastCalendar.get(Calendar.YEAR) == curCalendar.get(Calendar.YEAR)
						&& lastCalendar.get(Calendar.MONTH) == curCalendar.get(Calendar.MONTH)){
					if(cur_monthReqCount < lastObj.getMonthReqCount()){//说明有重启
//						cur_monthReqCount += lastObj.getMonthReqCount();
					}
				}
				obj.setMonthReqCount(cur_monthReqCount);

				long cur_dayReqCount = Long.parseLong(arr[8].trim());
				tmpObj.setDayReqCount(cur_dayReqCount);
				if(lastCalendar.get(Calendar.YEAR) == curCalendar.get(Calendar.YEAR)
						&& lastCalendar.get(Calendar.MONTH) == curCalendar.get(Calendar.MONTH)
						&& lastCalendar.get(Calendar.DAY_OF_MONTH) == curCalendar.get(Calendar.DAY_OF_MONTH)){
					if(cur_dayReqCount < lastObj.getDayReqCount()){//说明有重启
//						cur_dayReqCount += lastObj.getDayReqCount();
					}
				}
				obj.setDayReqCount(cur_dayReqCount);


			}


			obj.setHourReqCount(Long.parseLong(arr[9].trim()));
			obj.setSuccess(Long.parseLong(arr[10].trim()));
			obj.setFail(Long.parseLong(arr[11].trim()));
			obj.setFailAuth(Integer.parseInt(arr[12].trim()));
			obj.setFailSysLocal(Integer.parseInt(arr[13].trim()));
			obj.setFailSysRemote(Integer.parseInt(arr[14].trim()));
			obj.setFailOther(Integer.parseInt(arr[15].trim()));
			obj.setFailPreMiss(Integer.parseInt(arr[16].trim()));
			obj.setFailPreInvalid(Integer.parseInt(arr[17].trim()));
			obj.setFailPostInvalid(Integer.parseInt(arr[18].trim()));

			tmpObj.setHourReqCount(Long.parseLong(arr[9].trim()));
			tmpObj.setSuccess(Long.parseLong(arr[10].trim()));
			tmpObj.setFail(Long.parseLong(arr[11].trim()));
			tmpObj.setFailAuth(Integer.parseInt(arr[12].trim()));
			tmpObj.setFailSysLocal(Integer.parseInt(arr[13].trim()));
			tmpObj.setFailSysRemote(Integer.parseInt(arr[14].trim()));
			tmpObj.setFailOther(Integer.parseInt(arr[15].trim()));
			tmpObj.setFailPreMiss(Integer.parseInt(arr[16].trim()));
			tmpObj.setFailPreInvalid(Integer.parseInt(arr[17].trim()));
			tmpObj.setFailPostInvalid(Integer.parseInt(arr[18].trim()));
		} catch(Exception e){
			e.printStackTrace();
			System.out.println(line);
			return;
		}

//		System.out.println(obj);
		list.add(obj);
	}

	/**
	 * 覆盖模式
	 *
	 * @param output
	 */
	public static void write2file(String output){
		File file = new File(output);
		try{
			PrintWriter pw = new PrintWriter(file);
			pw.println(HourlyReqSummary.properties());
			list.forEach(obj -> {
				pw.println(obj.myToString());
			});
			pw.flush();
			pw.close();
		} catch(FileNotFoundException e){
			e.printStackTrace();
		}
	}


}
